/*****************************************************************************\

File:   otkCreateSweep.java

Date          Build     Author        Version   Comments
21-Dec-12    P-20-19    asonar         $$1       Created
28-Dec-12    P-20-20    asonar         $$2       Dumped info in a file
12-Feb-13	 P-20-23    pdeshpande     $$3       Modified in response to SPR 2162283
20-mar-15 P-30-05 gshmelev $$4  called GetCurrentSession

\****************************************************************************/

package com.ptc.otkjavaexamples;

import com.ptc.cipjava.*;
import com.ptc.pfc.pfcSession.*;
import com.ptc.pfc.pfcCommand.*;
import com.ptc.pfc.pfcGlobal.*;
import com.ptc.pfc.pfcModel.*;
import com.ptc.pfc.pfcModelItem.*;
import com.ptc.pfc.pfcFeature.*;
import com.ptc.pfc.pfcSolid.*;
import java.io.*;

import com.ptc.pfc.pfcFamily.*;
import com.ptc.pfc.pfcServer.*;
import com.ptc.pfc.pfcWindow.*;
import com.ptc.wfc.wfcSolidInstructions.*;
import com.ptc.wfc.wfcElementTree.*;
import com.ptc.wfc.wfcSession.*;
import com.ptc.pfc.pfcArgument.*;
import com.ptc.wfc.wfcFeatureInstructions.*;
import com.ptc.pfc.pfcSelect.*;
import com.ptc.wfc.wfcCollection.*;
import com.ptc.wfc.wfcSolid.*;
import com.ptc.pfc.pfcUI.*;
import com.ptc.wfc.wfcFeature.*; 
import com.ptc.wfc.wfcSection.SectionEntity.*;
import com.ptc.wfc.wfcSection.*;
import com.ptc.wfc.wfcElemIds.*;
import com.ptc.pfc.pfcBase.*;

/*====================================================================*\
  FUNCTION : otkCreateSweep
  PURPOSE  : This examples executes creation of sweep feature.
  \*====================================================================*/

class otkCreateSweep extends DefaultUICommandActionListener
{
    public void otkCreateSweep()
    {
    } 
    
    public void OnCommand()
    {
	addCreateSweep();
    } 
    
    public void addCreateSweep()
    {
	try
	    {  
		try
		    {
			Session session = pfcSession.GetCurrentSession ();
			Model currModel = session.GetCurrentModel();
			
			/* 
			   Set Message dialog options 
			*/
			MessageDialogOptions msgOpts = pfcUI.MessageDialogOptions_Create();
			MessageButtons buttons = MessageButtons.create();
			buttons.append(MessageButton.MESSAGE_BUTTON_OK);
			msgOpts.SetButtons(buttons);
			msgOpts.SetMessageDialogType(MessageDialogType.MESSAGE_WARNING);
			msgOpts.SetDialogLabel("OTK Sweep Feature Create ERROR");
			
			if(currModel == null)
			    {      
				session.UIShowMessageDialog("Model must be in current Session",msgOpts);
				throw new Exception("Method: pfcSession::GetCurrentModel \nMsg: otkSweepCreate");
			    }	  
			
			ModelType mdlType = currModel.GetType(); 		
			
			if((mdlType != ModelType.MDL_ASSEMBLY) && (mdlType != ModelType.MDL_PART))
			    {
				session.UIShowMessageDialog("Model must be part or assembly",msgOpts);
				throw new Exception("Method: pfcSession::GetType \nMsg: otkSweepCreate");
			    }
			
			else
			    {		
				WSolid wSolid = (WSolid)currModel;
				
				try
				    {
					ChainCollectionUIControls chainCntrls = ChainCollectionUIControls.create();
					chainCntrls.append(ChainCollectionUIControl.CHAINCOLLUI_ALLOW_ALL);
					
					/*
					  Collect curves for element PRO_E_STD_CURVE_COLLECTION_APPL.
					  This will be a trajectory for Sweep
					*/
					Collection trajCollection = wSolid.CollectCurves(chainCntrls,null,null,null);
					
					if(trajCollection == null)
					    throw new Exception("Method: pfcSession::CollectCurves \nMsg: otkSweepCreate");
					
					session.UIDisplayMessage("sweep_create_msg.txt","USER Select pivot direction",null);
					
					SelectionOptions dirSelopts = pfcSelect.SelectionOptions_Create("edge,curve,csys,surface,axis");
					dirSelopts.SetMaxNumSels(new Integer(1));	 
					
					/*
					  Select direction for element PRO_E_DIRECTION_REFERENCE
					  Direction to propagate with respect to trajectory 
					*/
					Selections dirSels = session.Select(dirSelopts, null);
					
					/*
					  Start building element tree using OTK ElementTree methods
					  Create incomplete sweep feature using element tree
					  Add circular section to it and redfine
					  Get sections of the sweep using Feature-Section methods
					  Replace circular section with elliptical one
					  Redefine feature using elliptical section
					*/
					otkBuildElementTree(trajCollection,dirSels);
				    }
				
				catch (Exception e)
				    {
					System.out.println("1: " + e);
				    }
				
			    }
			
		    }
		catch (Exception e)
		    {
			System.out.println("1: " + e);
		    }
	    }
	
	catch (Exception e)
	    {
		System.out.println("1: " + e);
	    }
	
    }
    
    static void otkBuildElementTree(Collection coll,Selections sels )
    {	
	
	try{
	    
	    Elements elements = Elements.create();
	    
	    /*
	      Create each element using wfcElement::Create() method
	      NOTE 1: Value of each element should be represented by pfcArgValue_ptr
	      except for compound and array elements for which value should be 0
	      
	      NOTE 2: Every element is placed at differnt  level in element tree present
	      Level starts with integer 0.
	      PRO_E_FEATURE_TREE is always a Level 0 element
	      
	      NOTE 3: All these elements should be added in a sequence of wfcElement
	      Latter same sequence will be used to build element tree
	      
	    */
	    
	    //PRO_E_FEATURE_TREE
	    Element elem_0_0 = wfcElementTree.Element_Create(wfcElemIds.PRO_E_FEATURE_TREE,null,0);
	    elements.append(elem_0_0);		
	    
	    //PRO_E_FEATURE_FORM
	    Element elem_1_1 = wfcElementTree.Element_Create(wfcElemIds.PRO_E_FEATURE_FORM,pfcArgument.CreateIntArgValue(4),1);
	    elements.append(elem_1_1);
	    
	    //PRO_E_SWEEP_TYPE
	    Element elem_1_2 = wfcElementTree.Element_Create(5528,pfcArgument.CreateIntArgValue(128),1);
	    elements.append(elem_1_2);
	    
	    //PRO_E_SWEEP_FRAME_COMP
	    Element elem_1_3 = wfcElementTree.Element_Create(wfcElemIds.PRO_E_SWEEP_FRAME_COMP,null,1);
	    elements.append(elem_1_3);
	    
	    //PRO_E_FRM_OPT_TRAJ
	    Element elem_2_0 = wfcElementTree.Element_Create(wfcElemIds.PRO_E_FRM_OPT_TRAJ,null,2);
	    elements.append(elem_2_0);
	    
	    //PRO_E_OPT_TRAJ
	    Element elem_3_0 = wfcElementTree.Element_Create(wfcElemIds.PRO_E_OPT_TRAJ,null,3);
	    elements.append(elem_3_0);
	    
	    //PRO_E_STD_SEC_METHOD
	    Element elem_4_0 = wfcElementTree.Element_Create(wfcElemIds.PRO_E_STD_SEC_METHOD,pfcArgument.CreateIntArgValue(26),4);
	    elements.append(elem_4_0);
	    
	    //PRO_E_STD_SEC_SELECT
	    Element elem_4_1 = wfcElementTree.Element_Create(wfcElemIds.PRO_E_STD_SEC_SELECT,null,4);
	    elements.append(elem_4_1);
	    
	    //PRO_E_STD_CURVE_COLLECTION_APPL
	    Element elem_5_0 = wfcElementTree.Element_Create(wfcElemIds.PRO_E_STD_CURVE_COLLECTION_APPL,null,5);
	    elem_5_0.SetElemCollection(coll);
	    elements.append(elem_5_0);
	    
	    //PRO_E_FRAME_SETUP
	    Element elem_2_1 = wfcElementTree.Element_Create(wfcElemIds.PRO_E_FRAME_SETUP,null,2);
	    elements.append(elem_2_1);
	    
	    //PRO_E_FRM_NORMAL
	    Element elem_3_1 = wfcElementTree.Element_Create(wfcElemIds.PRO_E_FRM_NORMAL,pfcArgument.CreateIntArgValue(512),3);
	    elements.append(elem_3_1);
	    
	    //PRO_E_FRM_PIVOT_DIR
	    Element elem_3_2 = wfcElementTree.Element_Create(wfcElemIds.PRO_E_FRM_PIVOT_DIR,null,3);
	    elements.append(elem_3_2);
	    
	    //PRO_E_DIRECTION_COMPOUND
	    Element elem_4_2 = wfcElementTree.Element_Create(wfcElemIds.PRO_E_DIRECTION_COMPOUND,null,4);
	    elements.append(elem_4_2);
	    
	    //PRO_E_DIRECTION_REFERENCE
	    Element elem_5_1 = wfcElementTree.Element_Create(wfcElemIds.PRO_E_DIRECTION_REFERENCE,pfcArgument.CreateSelectionArgValue(sels.get(0)),5);
	    elements.append(elem_5_1);
	    
	    //PRO_E_DIRECTION_FLIP
	    Element elem_5_2 = wfcElementTree.Element_Create(wfcElemIds.PRO_E_DIRECTION_FLIP,pfcArgument.CreateIntArgValue(1),5);
	    elements.append(elem_5_2);
	    
	    //PRO_E_FRM_ORIENT
	    Element elem_3_3 = wfcElementTree.Element_Create(wfcElemIds.PRO_E_FRM_ORIENT,pfcArgument.CreateIntArgValue(3),3);
	    elements.append(elem_3_3);
	    
	    //PRO_E_STD_FEATURE_NAME
	    Element elem_1_4 = wfcElementTree.Element_Create(wfcElemIds.PRO_E_STD_FEATURE_NAME,pfcArgument.CreateStringArgValue("OTK_SWEEP"),1);
	    elements.append(elem_1_4);
	    
	    //PRO_E_EXT_SURF_CUT_SOLID_TYPE
	    Element elem_1_5 = wfcElementTree.Element_Create(wfcElemIds.PRO_E_EXT_SURF_CUT_SOLID_TYPE,pfcArgument.CreateIntArgValue(917),1);
	    elements.append(elem_1_5);
	    
	    //PRO_E_REMOVE_MATERIAL
	    Element elem_1_6 = wfcElementTree.Element_Create(wfcElemIds.PRO_E_REMOVE_MATERIAL,pfcArgument.CreateIntArgValue(-1),1);
	    elements.append(elem_1_6);
	    
	    //PRO_E_FEAT_FORM_IS_THIN
	    Element elem_1_7 = wfcElementTree.Element_Create(wfcElemIds.PRO_E_FEAT_FORM_IS_THIN,pfcArgument.CreateIntArgValue(0 ),1);
	    elements.append(elem_1_7);
	    
	    
	    Session session = pfcSession.GetCurrentSession ();      
	    WSession wSession = (WSession)session;
	    
	    /*
	      Pass sequence of wfcElement to CreateElementTree() to get wfcElementTree object 
	    */
	    
	    ElementTree	elemTree = wSession.CreateElementTree(elements);
	    
	    /*
	      Create an incomplete sweep feature using element tree built up till now
	      
	      NOTE 1: We have not defined element PRO_E_SKETCHER yet
	      
	      NOTE 2: Feature must be created with option wfcFEAT_CR_INCOMPLETE_FEAT.
	      
	      NOTE 3: Mention feature regeneration options
	    */  
	    FeatCreateOptions featOpts = FeatCreateOptions.create();
	    featOpts.append(FeatCreateOption.FEAT_CR_INCOMPLETE_FEAT);
	    WRegenInstructions regenInstr = wfcSolidInstructions.WRegenInstructions_Create();
	    
	    Model currModel = session.GetCurrentModel();
	    WSolid currSolid = (WSolid)currModel;		
	    
	    WFeature sweepFeat = currSolid.WCreateFeature(elemTree,featOpts,regenInstr);
	    
	    /*
	      Extract element tree of incomplete sweep feature.
	      Get element PRO_E_SKETCHER
	      Get initialized  section from element PRO_E_SKETCHER
	      Modify section by adding required entities.
	      
	      NOTE 1: We must use initialized section returned by sketchSpvalue->GetSectionValue();
	      This section have defined location and orientation
	      based on frame created by incomplete  sweep feature
	      
	      NOTE 2: This is a 3D Section because it has a defined orientation & location
	      set by Creo
	    */
	    elemTree = sweepFeat.GetElementTree(null,FeatureElemTreeExtractOptions.FEAT_EXTRACT_NO_OPTS);
	    
	    Element sketchElem = GetSketcherElement(elemTree);
	    
	    SpecialValue sketchSpvalue = sketchElem.GetSpecialValueElem();
	    
	    Section sketch = sketchSpvalue.GetSectionValue();
	    
	    /*
	      Use Section APIs to add entities
	      NOTE: Intent Manager must be turn ON while adding entities
	      to ensure section resolution done properly 
	    */
	    sketch.SetIntentManagerMode(true);
	    Point2D center = wfcSession.CreatePoint2D(0.00,0.00);
	    
	    /*
	      Add an entity to section
	      NOTE: wfcSectionEntityCircle_ptr must be cast to wfcSectionEntity_ptr
	      before passing it to AddEntity.
	    */
	    
	    SectionEntityCircle circle = wfcSection.SectionEntityCircle_Create(center,40.00);
	    SectionEntity entity = (SectionEntity)circle;
	    
	    sketch.AddEntity(entity);
	    
	    circle = wfcSection.SectionEntityCircle_Create(center,30.00);
	    entity = (SectionEntity)circle;
	    
	    sketch.AddEntity(entity);
	    
	    sketch.SetIntentManagerMode(false);
	    
	    /*
	      Set modified section into PRO_E_SKETCHER element
	      NOTE 1: Sweep feature has to be redefined with modified element tree
	      
	      NOTE 2: Feature must be redefined with option wfcFEAT_CR_NO_OPTS
	      to ensure complete feature creation
	    */
	    sketchSpvalue.SetSectionValue(sketch);
	    sketchElem.SetSpecialValueElem(sketchSpvalue);
	    
	    featOpts.insert(0, FeatCreateOption.FEAT_CR_NO_OPTS);
   
	    sweepFeat.RedefineFeature(null,elemTree,featOpts,regenInstr);
	    
	    /*
	      Get section of the sweep feature and edit it 
	      NOTE: Here we are getting section of sweep using OTK Feature-Section methods
	      and not through element tree 
	    */
	    EditSweepSection(sweepFeat);
	}
	
	catch (Exception e)
	    {
		System.out.println("1: " + e);
	    }
	
    }
    
    
    
    static void EditSweepSection(WFeature feat)
    {
	
	try
	    {
		
		FileWriter file = new FileWriter ("sweep.xml");
		BufferedWriter fp_out_sweep = new BufferedWriter(file);	
		
		/*
		  Get sections in the sweep feature
		  NOTE: We are editing only section which is available to use
		  Section like curved trajectory is unavailable.
		*/
		
		Sections sections = feat.GetSections();
		
		Section section = sections.get(sections.getarraysize() - 1);
		
		/*
		  Replace circular entities by elliptical entities      
		*/
		
		section.SetIntentManagerMode(true);
		
		intseq ids = section.GetEntityIds();
		
		section.DeleteEntity(ids.get(ids.getarraysize() - 1));
		section.DeleteEntity(ids.get(ids.getarraysize() - 2));
		
		
		Point2D center = wfcSession.CreatePoint2D(0.00,0.00);
		
		SectionEntityEllipse ellipse = wfcSection.SectionEntityEllipse_Create(center,30.00,10.00);
		SectionEntity entity = (SectionEntity)ellipse;
		
		section.AddEntity(entity);
		
		ellipse = wfcSection.SectionEntityEllipse_Create(center,50.00,20.00);
		entity = (SectionEntity)ellipse;
		
		section.AddEntity(entity);
		
		section.SetIntentManagerMode(false);
		ElementTree elemTree = feat.GetElementTree(null,FeatureElemTreeExtractOptions.FEAT_EXTRACT_NO_OPTS);
		
		/*
		  Set modified section back to PRO_E_SKETCHER
		  NOTE : Here we are listing elements and filtering the list to get PRO_E_SKECTHER
		  once we got the element we are modifying the section value     
		*/
		
		Elements elements = elemTree.ListTreeElements();
		
		for(int ii=0;ii<elements.getarraysize();ii++)
		    {
			
			if(elements.get(ii).GetId()==wfcElemIds.PRO_E_SKETCHER && elements.get(ii).GetLevel()==3)
			    {
				elements.get(ii).GetSpecialValueElem().SetSectionValue(section);
				break;
			    }
		    }
		Session session = pfcSession.GetCurrentSession ();
		WSession wSession = (WSession)session;
		
		ElementTree newElemtree = wSession.CreateElementTree(elements);
		
	    newElemtree.WriteElementTreeToFile(ElementTreeFormat.ELEMTREE_XML, "sweep.xml");	  
		
		FeatCreateOptions featOpts = FeatCreateOptions.create();
		featOpts.append(FeatCreateOption.FEAT_CR_NO_OPTS);
		WRegenInstructions regenInstr =  wfcSolidInstructions.WRegenInstructions_Create();
		
		feat.RedefineFeature(null,newElemtree,featOpts,regenInstr);
	    }
	
	catch (Exception e)
	    {
		System.out.println("1: " + e);
	    }
	
	
    }
    
    
    static Element GetSketcherElement(ElementTree elemTree)
    {
	/*
	  Get PRO_E_SKECTHER element using wfcElementPath_ptr
	  
	  NOTE: To get an element with level greater than 1 you must
	  define element path with respect to PRO_E_FEATURE_TREE 
	  
	*/	
	try
	    {
		
		ElemPathItems sketchItems =  ElemPathItems.create();
		ElemPathItem sketchItem0 =  wfcElementTree.ElemPathItem_Create(ElemPathItemType.ELEM_PATH_ITEM_TYPE_ID,wfcElemIds.PRO_E_SWEEP_PROF_COMP);
		sketchItems.append(sketchItem0);
		ElemPathItem sketchItem1 =  wfcElementTree.ElemPathItem_Create(ElemPathItemType.ELEM_PATH_ITEM_TYPE_ID,wfcElemIds.PRO_E_SWEEP_SECTION);
		sketchItems.append(sketchItem1);
		ElemPathItem sketchItem2 =  wfcElementTree.ElemPathItem_Create(ElemPathItemType.ELEM_PATH_ITEM_TYPE_ID,wfcElemIds.PRO_E_SKETCHER);
		sketchItems.append(sketchItem2);
		
		ElementPath sketchPath = wfcElementTree.ElementPath_Create(sketchItems);
		
		Element element = elemTree.GetElement(sketchPath);
		
		return(element); 
		
	    }
	catch (Exception e)
    {
	System.out.println("1: " + e);
    }	
	
	return null;
    }	
    
    
}
